﻿#region All usings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using senSimulator.DrawableComponents.Vehicles;
#endregion


namespace senSimulator.DrawableComponents.TrafficLights.Types
{
    class TrafficLightForBicycles : TrafficLight
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public TrafficLightForBicycles(Game game, Vector2 spawnPosition, Texture2D[] textureNames, Vector2[] textureCenters, int posX, int posY, int rotationInDegrees, string trafficLightID, int distanceToTrafficLight)
            : base(game, spawnPosition, textureNames, textureCenters, posX, posY, rotationInDegrees, trafficLightID, distanceToTrafficLight)
        {}


        /// <summary>.
        /// Traffic light states for the Bicycle light
        /// </summary>
        /// <param name="state">New state of the traffic light</param>
        public override void ChangeTrafficLightState(int state)
        {
            switch (state)
            {
                case 0:     // OFF                
                    SwitchOff();
                    break;
                case 1:     // GREEN
                    _trafficLightState = state;
                    _errorAndOffstate = false;
                    break;
                case 3:     // RED
                    _trafficLightState = state - 1;
                    _errorAndOffstate = false;
                    break;
                case 7:     // Error
                    _trafficLightState = state - 7;
                    _errorAndOffstate = true;
                    break;
                default:    // NOT SUPPORTED
                    Console.WriteLine("Bicycle traffic light does not support state number: " + state);
                    break;
            }
        }


        /// <summary>
        /// Move a bike based on the different states
        /// </summary>
        public override void MoveTraffic(Controller controller)
        {
            for (int i = 0; i < _trafficLightQueueLength; i++)
            {
                // Get the bike and check if it has reached the end
                Bicycle bike;
                lock (_trafficLightQueue)
                {
                    bike = (Bicycle)_trafficLightQueue.ElementAt(i);
                }
                if (bike.IsFinished())
                {
                    RemoveTraffic(bike);
                    break;
                }

                // Check if the bike hits the sensor
                if (bike.GetCurrentWayPoint() == 1 && !bike.SensorTriggered() && bike.GetPosition() != bike.GetFirstWayPoint())
                {
                    bike.SetSensorTriggered(true);
                    controller.SendSensorTriggerToController(this.getName(), 1, bike.GetTo());
                }

                // If the bike hits the sensor/green, error or off light, MOVE!!!
                if (_trafficLightState == 1 || bike.SensorTriggered() || _errorAndOffstate)
                    bike.Move();
                else if (bike.GetCurrentWayPoint() == 0)
                {
                    if (i > 0)
                    {
                        Traffic previousBike;
                        lock (_trafficLightQueue)
                        {
                            previousBike = _trafficLightQueue.ElementAt(i - 1);
                        }
                        if (previousBike.SensorTriggered())
                            bike.Move();
                        else if ((Math.Abs(bike.GetPosition().X - previousBike.GetPosition().X) + Math.Abs(bike.GetPosition().Y - previousBike.GetPosition().Y) > previousBike.GetLength()))
                        {
                            bike.Move(previousBike.GetPosition(), previousBike.GetLength());
                        }
                        else
                            bike.Stop();
                    }
                    else
                        bike.Move();
                }
                else
                    bike.Stop();
            }
        }
    }
}
